package de.fhin.mas.agents.searcher.behaviours;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import de.fhin.mas.MASEvents;
import de.fhin.mas.agents.searcher.SearcherAgent;
import de.fhin.mas.ontology.SearchableObject;
import de.fhin.mas.ontology.TargetSearchResult;
import de.fhin.mas.util.MessageUtil;

/**
 * Dieses <tt>Behaviour</tt> erweitert den <tt>SearcherAgent</tt> um die
 * Zielsuche.
 * 
 * @author Andreas Schmidl
 * @author Thomas Schlaefer
 */
public class TargetSearch extends TickerBehaviour {

	/** Die eindeutige ID zur Serialisierung ueber das Netzwerk. */
	private static final long serialVersionUID = -5093414996378996162L;

	/**
	 * Die Referenz auf das zu suchende Objekt
	 */
	private SearchableObject targetObject = null;

	/** Die aktuelle Phase der "Simulation" ... 0, 1 oder 2. */
	private int simulationPhase;

	/**
	 * Erzeugt eine neue Instanz des <tt>TargetSearch</tt>-Behaviours.
	 * 
	 * @param parentAgent
	 *            Der Sucher-Agent, zu dem das Behaviour gehoeren soll.
	 */
	public TargetSearch(Agent parentAgent) {
		super(parentAgent, 2000);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void onTick() {
		SearcherAgent searcherAgent = (SearcherAgent) myAgent;

		List<AID> receivers = new ArrayList<AID>(2);
		AID manager = searcherAgent.getManager();
		if (manager == null) {
			searcherAgent.getLogger().log(Level.WARNING,
					"targetsearch: Kein Manager-Service verfügbar");
		} else {
			receivers.add(manager);
		}

		AID navigator = searcherAgent.getNavigator();
		if (navigator == null) {
			searcherAgent.getLogger().log(Level.WARNING,
					"targetsearch: Kein Navigator-Service verfügbar");
			return;
		}
		receivers.add(navigator);

		if (simulationPhase < 1) {
			searcherAgent.pauseTargetSearch();
			searcherAgent.initChangeOfLocationNecessary();
		} else if (simulationPhase == 1) {
			// Zielobjekt gefunden, sende TARGET_FOUND INFORM Message.
			ACLMessage targetFoundMsg = MessageUtil.buildMessage(null,
					MASEvents.TARGET_FOUND.getName(), ACLMessage.INFORM,
					receivers.toArray(new AID[receivers.size()]));

			// Content mit den Zieldaten befüllen.
			TargetSearchResult target = new TargetSearchResult(-54, 345);
			targetFoundMsg = searcherAgent.fillMsgContent(targetFoundMsg,
					target);
			searcherAgent.send(targetFoundMsg);

		} else if (simulationPhase == 2) {
			// ZielObjekt direkt vor dem Roboter, sende TARGET_FOUND INFORM
			// Message.
			ACLMessage targetFoundMsg = MessageUtil.buildMessage(null,
					MASEvents.TARGET_FOUND.getName(), ACLMessage.INFORM,
					receivers.toArray(new AID[receivers.size()]));

			// Content mit den Zieldaten befüllen.
			TargetSearchResult target2 = new TargetSearchResult(0, 10);
			targetFoundMsg = searcherAgent.fillMsgContent(targetFoundMsg,
					target2);
			searcherAgent.send(targetFoundMsg);
		}

		// Den Iterationszähler erhöhen für unsere "Simulation".
		simulationPhase++;
	}

	/** Setzt das aktuelle Suchobjekt */
	public void setTargetObject(SearchableObject targetObject) {
		this.targetObject = targetObject;
	}

	/** Gibt das aktuelle Suchobjekt zurück */
	public SearchableObject getTargetObject() {
		return targetObject;
	}

	/** Setzt das "Simulations-Szenario" zurück. */
	public void resetSimulation() {
		simulationPhase = 0;
	}

}
